/*
	Copyright (c) 2010 Canadensys
*/
package net.canadensys.dataportal.vascan;
import java.io.Serializable;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import net.canadensys.dataportal.utils.HibernateUtil;

import org.apache.solr.analysis.ISOLatin1AccentFilterFactory;
import org.apache.solr.analysis.LowerCaseFilterFactory;
import org.apache.solr.analysis.StandardFilterFactory;
import org.apache.solr.analysis.StandardTokenizerFactory;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.AnalyzerDef;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Fields;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.hibernate.search.annotations.Store;
import org.hibernate.search.annotations.TokenFilterDef;
import org.hibernate.search.annotations.TokenizerDef;

@Entity
@Table(name="vernacularname")
@AnalyzerDef(name = "noAccentAnalyzer",
		tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), 
		filters = {
			@TokenFilterDef(factory = LowerCaseFilterFactory.class),
			@TokenFilterDef(factory = StandardFilterFactory.class),
			@TokenFilterDef(factory = ISOLatin1AccentFilterFactory.class)
		}
)
@Cache(region="VernacularName", usage = CacheConcurrencyStrategy.READ_WRITE)
public class VernacularName implements Serializable {
	private static final long serialVersionUID = -3345329007016142805L;
	private int				id;
    @Fields({
    	@Field(index=Index.TOKENIZED, store=Store.YES),
    	@Field(name = "namenoaccent", index=Index.UN_TOKENIZED, store=Store.YES, analyzer=@Analyzer(definition="noAccentAnalyzer"))
    })
	private String			name;
	@IndexedEmbedded
	private Status			status;
	private Taxon			taxon;
	@Field(index=Index.UN_TOKENIZED, store=Store.YES)
	private String			language;
	@IndexedEmbedded
	private Reference 		reference;
	@Temporal(TemporalType.TIMESTAMP)
	private	Date			cdate;
	@Temporal(TemporalType.TIMESTAMP)
	private	Date			mdate;	
	
	@Transient
	private String				error;
	
	@Transient
	/**
	 * @return the error
	 */
	public String getError() {
		return error;
	}

	/**
	 * @param error the error to set
	 */
	public void setError(String error) {
		this.error = error;
	}
	
	/**
	 * @return the id
	 */
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public int getId() {
		return id;
	}
	
	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}
	
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	@ManyToOne
	@JoinColumn(name="statusid")
	public Status getStatus() {
		return status;
	}

	/**
	 * @param status
	 */
	public void setStatus(Status status) {
		this.status = status;
	}
	
	@ManyToOne
	@JoinColumn(name="taxonid")
	public Taxon getTaxon() {
		return taxon;
	}

	/**
	 * @param taxon
	 */

	public void setTaxon(Taxon taxon) {
		this.taxon = taxon;
	}
	
	/**
	 * @return the language
	 */
	public String getLanguage() {
		return language;
	}
	
	/**
	 * @param language
	 */
	public void setLanguage(String language) {
		this.language = language;
	}
	
	@ManyToOne
	@JoinColumn(name="referenceid")
	public Reference getReference() {
		return reference;
	}

	/**
	 * @param refrence
	 */
	public void setReference(Reference reference) {
		this.reference = reference;
	}

	/**
	 * @return the creation date
	 */
	public Date getCdate() {
		return cdate;
	}

	/**
	 * @param cdate
	 */
	public void setCdate(Date cdate) {
		this.cdate = cdate;
	}

	/**
	 * @return the modification date
	 */
	public Date getMdate() {
		return mdate;
	}

	/**
	 * @param mdate
	 */
	public void setMdate(Date mdate) {
		this.mdate = mdate;
	}

	/**
	 * 
	 */
	public boolean save(){
		boolean success = false;
		org.hibernate.Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession();
		hibernateSession.beginTransaction();
		try{
			hibernateSession.saveOrUpdate(this);
			success = true;
		}
		catch(Exception e){
			this.error = e.getMessage();
		}
		return success;
	}
	
	/**
	 * 
	 * @return
	 */
	public boolean delete(){
		boolean success = false;
		org.hibernate.Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession();
		hibernateSession.beginTransaction();
		try{
			hibernateSession.delete(this);
			success = true;
		}
		catch(Exception e){
			this.error = e.getMessage();
		}
		return success;
	}
	
	@Override
	/**
	 * toString is mainly used in the admin backend, where a basic string representation
	 * is dumped to the logfile, in a before/after fashion (changed from / changed to) 
	 */
	public String toString() {
		String delimiter = " ";
		//String newline = "\n";
		StringBuffer lookup = new StringBuffer("");
		lookup.append(this.id).append(delimiter);
		lookup.append(this.name).append(delimiter);
		lookup.append(this.status).append(delimiter);
		lookup.append(this.taxon.getLookup().getCalname()).append(delimiter);
		lookup.append(this.getLanguage()).append(delimiter);	
		lookup.append(this.getReference().getReferenceshort());
		return lookup.toString();
	}	
}
